/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2023. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

/*!
 * @file ac780x_gpio.h
 *
 * @brief This file provides gpio integration functions interface.
 *
 */

#ifndef _AC780X_GPIO_H
#define _AC780X_GPIO_H

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* ===========================================  Includes  =========================================== */
#include "ac7803x.h"

/* ============================================  Define  ============================================ */
/*!
 * @brief GPIO instance index macro, GPIOx should be GPIOA/GPIOB/GPIOC/GPIOD.
 */
#define GPIO_INDEX(GPIOx)    ((GPIO_IndexType)(((uint32_t)(GPIOx) - GPIOA_BASE) / 0x30U))

/*!< GPIO pin max number: 0~57 */
#define GPIO_PIN_MAX_NUM     (58UL)

/*!< GPIO base addr parameter check */
#define IS_GPIO_PERIPH(GPIOx) (((GPIOx) == GPIOA) || ((GPIOx) == GPIOB) || ((GPIOx) == GPIOC) || ((GPIOx) == GPIOD))

/*!< GPIO pin bit action check, should be 0 or 1 */
#define IS_GPIO_BIT_ACTION(action) (((action) == ENABLE) || ((action) == DISABLE))

/* ===========================================  Typedef  ============================================ */

/*!< GPIO module index enumeration. */
typedef enum
{
    GPIOA_INDEX = 0U,       /*!< 0: GPIOA index */
    GPIOB_INDEX,            /*!< 1: GPIOB index */
    GPIOC_INDEX,            /*!< 2: GPIOC index */
    GPIOD_INDEX,            /*!< 3: GPIOD index */
    GPIO_INDEX_MAX
} GPIO_IndexType;

typedef enum{
    GPIO_PIN0_MASK    = (uint32_t)0x1U,
    GPIO_PIN1_MASK    = (uint32_t)0x2U,
    GPIO_PIN2_MASK    = (uint32_t)0x4U,
    GPIO_PIN3_MASK    = (uint32_t)0x8U,
    GPIO_PIN4_MASK    = (uint32_t)0x10U,
    GPIO_PIN5_MASK    = (uint32_t)0x20U,
    GPIO_PIN6_MASK    = (uint32_t)0x40U,
    GPIO_PIN7_MASK    = (uint32_t)0x80U,
    GPIO_PIN8_MASK    = (uint32_t)0x100U,
    GPIO_PIN9_MASK    = (uint32_t)0x200U,
    GPIO_PIN10_MASK   = (uint32_t)0x400U,
    GPIO_PIN11_MASK   = (uint32_t)0x800U,
    GPIO_PIN12_MASK   = (uint32_t)0x1000U,
    GPIO_PIN13_MASK   = (uint32_t)0x2000U,
    GPIO_PIN14_MASK   = (uint32_t)0x4000U,
    GPIO_PIN15_MASK   = (uint32_t)0x8000U,
    GPIO_PIN_ALL_MASK = (uint32_t)0xFFFFU,
} GPIO_PinMaskType;

typedef enum{
    GPIO_PIN0 = 0U,
    GPIO_PIN1,
    GPIO_PIN2,
    GPIO_PIN3,
    GPIO_PIN4,
    GPIO_PIN5,
    GPIO_PIN6,
    GPIO_PIN7,
    GPIO_PIN8,
    GPIO_PIN9,
    GPIO_PIN10,
    GPIO_PIN11,
    GPIO_PIN12,
    GPIO_PIN13,
    GPIO_PIN14,
    GPIO_PIN15,
    GPIO_PIN_MAX_ONE_GROUP,
} GPIO_PinType;
/*!< GPIO pin check, should be 0~15 */
#define IS_GPIO_PIN(PINx) ((PINx) <= GPIO_PIN15)

/*!< GPIO pin level enumeration */
typedef enum
{
    GPIO_LEVEL_LOW = 0U,
    GPIO_LEVEL_HIGH
} GPIO_LevelType;

typedef enum
{
    GPIO_IN = 0U,
    GPIO_OUT
} GPIO_DirType;
/*!< GPIO pin direction check, should be 0 or 1 */
#define IS_GPIO_DIR(dir) (((dir) == GPIO_IN)  || ((dir) == GPIO_OUT))

typedef enum
{
    GPIO_FLOATING = 0U,
    GPIO_PU,
    GPIO_PD
} GPIO_PuPdType;

typedef enum
{
    GPIO_FUN6 = 0U,
    GPIO_FUN0,
    GPIO_FUN1,
    GPIO_FUN2,
    GPIO_FUN3,
    GPIO_FUN4,
    GPIO_FUN5
} GPIO_FunType;
/*!< GPIO PINMUX function check, should be 0~6 */
#define IS_GPIO_PINMUX(func) (((func) == GPIO_FUN0) || ((func) == GPIO_FUN1) || \
                              ((func) == GPIO_FUN2) || ((func) == GPIO_FUN3) || \
                              ((func) == GPIO_FUN4) || ((func) == GPIO_FUN5) || \
                              ((func) == GPIO_FUN6))

typedef enum
{
    GPIO_DRIVING_4MA = 0U,
    GPIO_DRIVING_8MA,
    GPIO_DRIVING_12MA,
    GPIO_DRIVING_16MA
} GPIO_DrivingType;

typedef struct
{
    GPIO_DirType  GPIO_Dir;
    GPIO_PuPdType GPIO_PuPd;
    GPIO_FunType  GPIO_Fun;
} GPIO_ModeType;

typedef struct
{
    GPIO_PinType      GPIO_Pin;             /*!< pin: 0~15 */
    GPIO_ModeType     GPIO_Mode;
    GPIO_DrivingType  GPIO_Driving;
} GPIO_ConfigType;

typedef enum
{
    EXTI_TRIGGER_FALLING = 0U,
    EXTI_TRIGGER_RISING,
    EXTI_TRIGGER_RISING_FALLING,
} EXTI_TriggerType;
/*!< GPIO exti trigger check, should be 0~2 */
#define IS_EXTI_TRIGGER(trigger) (((trigger) == EXTI_TRIGGER_FALLING) || \
                                  ((trigger) == EXTI_TRIGGER_RISING) ||  \
                                  ((trigger) == EXTI_TRIGGER_RISING_FALLING))

typedef struct
{
    uint32_t *PMUXx;                 /*!< PMUX index, can be configured by GPIO_GetPMUXConfig() */
    uint32_t PMUXx_PFSEL;            /*!< PFSEL index, can be configured by GPIO_GetPMUXConfig() */
} GPIO_ConfigPmuxType;

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */
/*!
 * @brief Set several GPIO pins' Pmux and pin function.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] config: GPIO_Config type structure pointer
 * @return none
 */
void GPIO_Init(GPIO_Type *GPIOx, const GPIO_ConfigType *config);

/*!
 * @brief reset all GPIO: disable interrupt and disable clock
 *
 * @param[in] none
 * @return none
 */
void GPIO_DeInit(void);

/*!
 * @brief Set GPIO pin level by GPIO_ODR register.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] pinVal: Pin level
 *                   -GPIO_LEVEL_LOW
 *                   -GPIO_LEVEL_HIGH
 * @return none
 */
void GPIO_SetPinLevel(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_LevelType pinLevel);

/*!
 * @brief Get GPIO pin level by GPIO_IDR register.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @return pinVal: Pin level
 *                   -GPIO_LEVEL_LOW
 *                   -GPIO_LEVEL_HIGH
 */
GPIO_LevelType GPIO_GetPinLevel(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
 * @brief  Set Select GPIO pin by GPIO_BSRR register.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @return none
 */
void GPIO_SetPinBit(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
 * @brief Reset Select GPIO pin.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @return 0: success, -1: GPIO_PinNum is too large
 */
void GPIO_ResetPinBit(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
 * @brief Set GPIO port value by GPIO_ODR register.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] portLevel: GPIOx_ODR register value, it can be 0~0xFFFF
 * @return none
 */
void GPIO_SetPortLevel(GPIO_Type *GPIOx, uint16_t portLevel);

/*!
 * @brief Get GPIO port value by GPIO_IDR register.
 *
 * @param[in] GPIOx: GPIO type structure pointer:
 *                   -GPIOA
 *                   -GPIOB
 *                   -GPIOC
 *                   -GPIOD
 * @return portLevel: GPIOx_ODR register value, it can be 0~0xFFFF
 */
uint16_t GPIO_GetPortLevel(GPIO_Type *GPIOx);

/*!
 * @brief  Set a GPIO pin's Pmux and pin function.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] functionx: GPIO function
 *                   -GPIO_FUN0
 *                   -GPIO_FUN1
 *                   -GPIO_FUN2
 *                   -GPIO_FUN3
 * @return none
 */
void GPIO_SetFunc(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_FunType functionx);

/*!
 * @brief Get a GPIO pin's Pmux function.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @return GPIO pin Pmux function
 */
GPIO_FunType GPIO_GetPinFunc(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
 * @brief Set several GPIO pins' Pmux( pin function ).
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] pinMask: GPIO pin mask value indicate which GPIO need to be modifyed
 * @param[in] functionx: GPIO function
 *                   -GPIO_FUN0
 *                   -GPIO_FUN1
 *                   -GPIO_FUN2
 *                   -GPIO_FUN3
 * @return none
 */
void GPIO_SetFuncGroup(GPIO_Type *GPIOx, uint16_t pinMask, GPIO_FunType functionx);

/*!
 * @brief Set GPIO pin's mode, input or output.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] pinDir: GPIO direction, input or output
 *                   -GPIO_IN
 *                   -GPIO_OUT
 * @return none
 */
void GPIO_SetDir(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_DirType pinMode);

/*!
 * @brief Get a GPIO pin's direction, input or output.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @return GPIO pin's direction
 *                   -GPIO_IN
 *                   -GPIO_OUT
 */
GPIO_DirType GPIO_GetDir(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
 * @brief Set several GPIO pins' pin mode.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] pinMask: GPIO pin mask value indicate which gpios need to be modifyed
 * @param[in] pinDir: GPIO direction, input or output
 *                   -GPIO_IN
 *                   -GPIO_OUT
 * @return none
 */
void GPIO_SetDirGroup(GPIO_Type *GPIOx, uint16_t pinMask, GPIO_DirType pinDir);

/*!
 * @brief Set GPIO pin's pull-up resistor.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] enable: enable or disable pull-up resistor
 *                   -ENABLE
 *                   -DISABLE
 * @return none
 */
void GPIO_SetPullup(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, ACTION_Type enable);

/*!
 * @brief Set GPIO pin's pull-down resistor.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] enable: enable or disable pull-down resistor
 *                   -ENABLE
 *                   -DISABLE
 * @return none
 */
void GPIO_SetPulldown(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, ACTION_Type enable);

/*!
 * @brief Set a GPIO pin's driving ability.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] E4E2Value: Driving current select
 *                   -GPIO_DRIVING_4MA
 *                   -GPIO_DRIVING_8MA
 *                   -GPIO_DRIVING_12MA
 *                   -GPIO_DRIVING_16MA
 * @return none
 */
void GPIO_SetDrivingAbility(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_DrivingType E4E2Value);

/*!
 * @brief Set GPIO as high-Z state or floating input state.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] enable: enable or disable high-z state. If disable high-z, IO will be set to floating input.
 *                   -ENABLE
 *                   -DISABLE
 * @return none
 */
void GPIO_SetHighZ(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, ACTION_Type enable);

/*!
 * @brief Enable a GPIO pin's external interrupt and trigger condition.
 *
 * @param[in] GPIOx: GPIO type structure pointer,x can be A.B.C.D
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] risingFallingEdge: GPIO's external interrupt set,value can be
 *                   -EXTI_TRIGGER_FALLING
 *                   -EXTI_TRIGGER_RISING
 *                   -EXTI_TRIGGER_RISING_FALLING
 * @return none
 */
void GPIO_EnableExtInterrupt(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, EXTI_TriggerType risingFallingEdge);

/*!
 * @brief Disable a GPIO pin's external interrupt and trigger condition.
 *
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @return  none
 */
void GPIO_DisableExtInterrupt(GPIO_PinType GPIO_Pin);

/*!
 * @brief Get a GPIO pin's pending external interrupt IRQ number, a 16bit mask which represents the GPIO's group internal position.
 *
 * @param[in] none
 * @return GPIO's Pending external interrupt 16 bits mask
 */
uint16_t GPIO_GetPendingExtInterrupt(void);

/*!
 * @brief Clear a GPIO pin's external interrupt pending flag
 *
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @return none
 */
void GPIO_ClearPendingExtInterrupt(GPIO_PinType GPIO_Pin);

/*!
 * @brief Set GPIO interrupt callback function, Pin0~2 has the independent interrupt vector,
 *         Pin3~8 share the same interrupt vector, and Pin9~15 share the same interrupt vector.
 *
 * @param[in] GPIO_Pin: GPIO_Pin type num:
 *                   -GPIO_PIN0
 *                   -GPIO_PIN1
 *                   -GPIO_PIN2
 *                   - ...
 *                   -GPIO_PIN15
 * @param[in] callback: GPIO interrupt callback function, which will be called in EXTIx_IRQHandler()
 * @return none
 */
void GPIO_SetCallback(GPIO_PinType GPIO_Pin, const DeviceCallback_Type callback);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _AC780X_GPIO_H */

/* =============================================  EOF  ============================================== */
